package com.tianletan;

import java.io.IOError;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

public class GroupChatServer {
    //定义属性
    private Selector selector;

    private ServerSocketChannel serverSocketChannel;

    private static final int PORT = 6667;

    //构造器
    public GroupChatServer(){

        try{
            selector = Selector.open(); //获取选择器
            serverSocketChannel = ServerSocketChannel.open(); //获取serverSocketChannel
            serverSocketChannel.socket().bind(new InetSocketAddress(PORT)); //绑定端口
            serverSocketChannel.configureBlocking(false); //设置NIO非阻塞模式
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); //将serverSocketChannel注册到selector上

        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public void listen(){

        try{
            //循环监听
            while(true){
                int count = selector.select();
                if(count > 0){
                    //遍历得到的selectionKey集合
                    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                    while(iterator.hasNext()){
                        //取出selectionKey
                        SelectionKey selectionKey = iterator.next();

                        //根据不同事件完成对应业务逻辑
                        if(selectionKey.isAcceptable()){
                            //发生accept事件可获得socket连接
                            SocketChannel socketChannel = serverSocketChannel.accept();
                            socketChannel.configureBlocking(false);
                            //将该socket注册到selector上
                            socketChannel.register(selector, SelectionKey.OP_READ);
                            //提示
                            System.out.println("客户端 " + socketChannel.getRemoteAddress() + " 已上线!");
                        }
                        if(selectionKey.isReadable()){
                            //处理读事件
                            read(selectionKey);
                        }

                        //删除当前key，防止重复处理
                        iterator.remove();
                    }
                }else{
//                    System.out.println("等待客户端连接...");
                }
            }


        }catch (Exception e){
            e.printStackTrace();
        }finally {

        }
    }

    private void read(SelectionKey key){
        SocketChannel channel = null;
        try{
            channel = (SocketChannel) key.channel();
            //开始读数据
            ByteBuffer buffer = ByteBuffer.allocate(1024); //字节
            int count = channel.read(buffer);
            if(count > 0){ // ?
                String msg = new String(buffer.array());
                System.out.println("客户端 " + msg);
                //向其他客户端转发消息
                sendMsgToOtherClient(msg, channel);
            }
        }catch(IOException e1){
            try{
                System.out.println(channel.getRemoteAddress() + " 已离线");
                key.cancel(); //取消注册
                channel.close(); //关闭通道
            }catch (IOException e2){
                e2.printStackTrace();
            }
        }
    }

    private void sendMsgToOtherClient(String msg, SocketChannel selfChannel) throws IOException {
//        System.out.println("服务器转发消息中...");
        //遍历所有注册到selector上的socketChannel并排除selfChannel
        for (SelectionKey key : selector.keys()) {
            Channel channel = key.channel();
            if(channel instanceof SocketChannel && channel != selfChannel){
                SocketChannel socketChannel = (SocketChannel) channel;
                ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());
                socketChannel.write(buffer);
            }
        }
    }

    public static void main(String[] args) {
        GroupChatServer chatServer = new GroupChatServer();
        chatServer.listen();
    }
}
